﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using blackhouse.Aparts.Web.Model;
using blackhouse.Aparts.Web.Presenter;
using blackhouse.Aparts.Web.View;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Business.Opinions;
using blackhouse.BlackApart.Web;
using blackhouse.BlackApart.Web.Navigation;
using blackhouse.JavaScript.JQuery;
using blackhouse.mojoPortalExtend.Breadcrumbs;
using blackhouse.Web.Controls;
using mojoPortal.Business;
using mojoPortal.Business.WebHelpers;
using mojoPortal.Web;

namespace blackhouse.Aparts.Web.Pages {
    public partial class OpinionDetails : NonCmsBasePage, IOpinionDetailsView {

        #region Fields

        private int fOpinionId = -1;
        private OpinionDetailsPresenter presenter;
        private PageSettings cmsOpinionPage;
        private mojoPortalExtend.PageProvider pageProvider;
        private double averageRating;
        private double similarAverageRating;
        
        #endregion

        #region Properties

        public mojoPortalExtend.PageProvider PageProvider {
            get {
                if (this.pageProvider == null)
                    this.pageProvider = new mojoPortalExtend.PageProvider();
                return this.pageProvider;
            }
        }

        public PageSettings CMSOpinionPage {
            get {
                if (this.cmsOpinionPage == null)
                    this.cmsOpinionPage = this.GetCmsOpinionPage();
                return this.cmsOpinionPage;
            }
        }

        public int OpinionId {
            get {
                if (this.fOpinionId == -1)
                    this.fOpinionId = this.GetOpinionId();
                return this.fOpinionId;
            }
        }

        public double AverageRating {
            get {
                return this.averageRating;
            }
            set {
                this.averageRating = value;
                this.ltlAvgOpinion.Text = this.averageRating.ToString("F2");
            }
        }

        public double SimilarAverageRating {
            get {
                return this.similarAverageRating;
            }
            set {
                this.similarAverageRating = value;
                this.ltlSimilarOpinions.Text = this.similarAverageRating.ToString("F2");
            }
        }

        public bool PublishButtonVisible {
            get {
                return this.lnkPublish.Visible;
            }
            set {
                this.lnkPublish.Visible = value;
            }
        }

        public List<IOpinion> SimilarOpinions {
            get {
                return this.rptOpinions.DataSource as List<IOpinion>;
            }
            set {
                this.rptOpinions.DataSource = value;
            }
        }

        public IDictionary<string, double> CategoryValues {
            get {
                return this.rptReviewCategories.DataSource as IDictionary<string, double>;
            }
            set {
                this.rptReviewCategories.DataSource = value;
            }
        }

        private bool haveOpinionAdminPriv;
        private bool haveOpinionAdminPrivSetted;

        public bool HaveOpinionAdminPriv {
            get {
                if (!this.haveOpinionAdminPrivSetted) {
                    this.haveOpinionAdminPriv = WebUser.IsAdminOrContentAdminOrContentPublisher || WebUser.IsInRole("Opinions");
                    this.haveOpinionAdminPrivSetted = true;
                }
                return this.haveOpinionAdminPriv;
            }
        }

        #endregion

        #region Methods

        public int GetUserId() {
            if (User.Identity.IsAuthenticated)
                return SiteUtils.GetCurrentSiteUser().UserId;
            else return 0;
        }

        private PageSettings GetCmsOpinionPage() {
            return this.PageProvider.FindCmsPageByFunctionality("opinions");
        }

        protected override void OnPreInit(EventArgs e) {
            this.AllowSkinOverride = true;
            HttpContext.Current.Items.Add("skin", "blackhouse");
            HttpContext.Current.Items.Add("short-top", true);


            base.OnPreInit(e);
        }

        protected override void OnInit(EventArgs e) {
            base.OnInit(e);

            this.AddClassToBody("short-top");
            this.presenter = new OpinionDetailsPresenter(this, new ApartsOpinionsModel());
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);

            this.presenter.LoadView();

            if (this.RequestHtmlSnapshot()) {
                this.presenter.LoadSimilarOpinions();
            }
            else {
                this.rptOpinions.Visible = false;
                this.opinionsLoad.Visible = true;
                this.SupportAjaxContent();
            }
            this.DataBind();
            this.AdditionalMetaMarkup = "<meta name=\"fragment\" content=\"!\">";
        }

        private void SetSeo(View.DisplayOpinion displayOpinion) {
            NavigationProvider nav = NavigationProvider.Instance();
            string url = nav.GetUrl(displayOpinion.opinion);

            string name = displayOpinion.Publisher.FirstName;
            if (!string.IsNullOrEmpty(displayOpinion.Publisher.LastName)) {
                name += " ";
                name += displayOpinion.Publisher.LastName;
            }
            name += ", ";
            name += displayOpinion.Country;
            name += " - ";
            name += displayOpinion.PublishedDateFormatted;

            string name2 = "Opinia do apartamentu " + displayOpinion.ApartmentText + " | " + name;

            this.PageProvider.SetPageTitle(name2);
            this.PageProvider.SetPageDescription(name2);
            this.PageProvider.SetCanonicalUrl(url);

            PageSettings opinionPage = this.CMSOpinionPage;
            string opinionUrl = string.Empty;
            if (opinionPage != null) {
                BreadcrumbsAccess breadcrumbs = new BreadcrumbsAccess();
                opinionUrl = GetOpinionUrl(opinionPage);
                breadcrumbs.AddCrumb(opinionPage.PageName, opinionUrl);

                if (displayOpinion.apartment != null)
                    breadcrumbs.AddCrumb(displayOpinion.apartment.ShortName, opinionUrl + "?apartment=" + displayOpinion.apartment.Id);

                breadcrumbs.AddCrumb(name, url);
            }

            if (Request.UrlReferrer != null) {
                this.lnkBacklinkToOpinion.Visible = false;
                this.lnkBacklink.NavigateUrl = Request.UrlReferrer.ToString();
            }
            else {
                this.lnkBacklink.Visible = false;
                this.lnkBacklinkToOpinion.NavigateUrl = opinionUrl;
            }

        }

        private string GetOpinionUrl(PageSettings opinionPage) {
            string url = opinionPage.Url;
            url = url.ReplaceEx("~/", "/");
            if (url.EndsWith("/"))
                url = url.Substring(0, url.Length - 1);
            return UrlUtils.LocalizeUrl(url);
        }

        private bool RequestHtmlSnapshot() {
            return Request.QueryString.AllKeys.Contains("_escaped_fragment_");
        }

        private void SupportAjaxContent() {
            this.opinionId.Value = this.OpinionId.ToString();
            JQueryLibraries jql = new JQueryLibraries();
            jql.IncludeJQueryTemplates();
            jql.IncludeJQueryWaypoints();

            jql.IncludeFileBasedOnJQuery("blackhouse.Aparts.Web.Scripts.opinion-details.js,blackhouse.Aparts.Web");

            blackhouse.Web.Controls.TemplateControl.TemplateControl tplCtrl = new blackhouse.Web.Controls.TemplateControl.TemplateControl();
            tplCtrl.TemplateId = "opinion-item";
            tplCtrl.Controls.Add(Page.LoadControl("~/Modules/OpinionItem.ascx"));
            this.Page.Header.Controls.Add(tplCtrl);
        }

        public override void DataBind() {
            if (this.rptOpinions.DataSource != null)
                this.rptOpinions.DataBind();
            this.rptReviewCategories.DataBind();

            base.DataBind();
        }

        private int GetOpinionId() {
            int rOpinionId = 0;
            string sOpinionId = Request.QueryString["opinion"];
            if (!string.IsNullOrEmpty(sOpinionId) && Int32.TryParse(sOpinionId, out rOpinionId))
                return rOpinionId;
            else
                return 0;
        }

        public void ShowNoOpinionInfo() {
            this.pnlOpinion.Visible = false;
            this.pnlNoOpinion.Visible = true;
        }

        public void DisplayOpinion(View.DisplayOpinion displayOpinion) {
            this.imgAvatar.ImageUrl = displayOpinion.AvatarImageUrl;
            this.imgAvatar.ToolTip = displayOpinion.Publisher.Category;
            this.ltlPublisherName.Text = displayOpinion.Publisher.FirstName + " " + displayOpinion.Publisher.LastName + ", " + displayOpinion.Country;
            this.ltlPublishDate.Text = displayOpinion.PublishedDateFormatted;
            this.lblInPlus.Text = displayOpinion.InPlusOpinionFormatted;
            this.lblInMinus.Text = displayOpinion.InMinusOpinionFormatted;

            if (displayOpinion.HaveAnswer) {
                this.pnlAnswer.Visible = true;
                this.lblAnswer.Text = displayOpinion.Answer;
            }

            this.SetSeo(displayOpinion);
        }

        public void HideSimilarOpinions() {
            this.pnlSimOpinionTitle.Visible = false;
            this.pnlSimilarOpinions.Visible = false;
        }

        public void DisplayAssociatedApartment(IApartmentGroup group) {
            this.apartmentLine.PopulateControl(group);
        }

        public void EnableEditMode() {
            this.ReplaceToEdit(this.lblInPlus, this.txtInPlus);
            this.ReplaceToEdit(this.lblInMinus, this.txtInMinus);
            this.ReplaceToEdit(this.lblAnswer, this.txtAnswer);
            this.pnlAnswer.Visible = true;
            this.pnlActions.Visible = true;
        }

        private void ReplaceToEdit(Literal literal, TextBox txt) {
            txt.Text = literal.Text;
            txt.Visible = true;
            literal.Visible = false;
        }

        protected void lnkPublish_Click(object sender, EventArgs e) {
            this.SaveOpinion(true);
        }

        public void ShowPublishedInfo() {
            this.notifPublished.Visible = true;
        }

        protected void lnkSave_Click(object sender, EventArgs e) {
            this.SaveOpinion(false);
        }

        private void SaveOpinion(bool withPublish) {
            string inPlus = Request[this.txtInPlus.UniqueID];
            string inMinus = Request[this.txtInMinus.UniqueID];
            string answer = Request[this.txtAnswer.UniqueID];
            this.presenter.SaveOpinion(inPlus, inMinus, answer, withPublish);
        }

        public void ShowSavedInfo(bool status) {
            this.notifSaveSuccess.Visible = status;
            this.notifErrorSave.Visible = !status;
        }

        #endregion

    }
}